/**
 * @author Edison Parra <epmespam@gmail.com>
 */
package co.edu.unal.satacredito.database.dao;

import co.edu.unal.satacredito.database.entity.NotSyntaxTransaction;
import co.edu.unal.satacredito.database.exception.NonexistentEntityException;
import co.edu.unal.satacredito.database.exception.PreexistingEntityException;
import co.edu.unal.satacredito.database.exception.UnreachableHostException;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.Key;
import com.google.code.morphia.mapping.Mapper;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;
import com.google.code.morphia.query.UpdateResults;
import com.mongodb.WriteResult;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bson.types.ObjectId;

public class NotSyntaxTransactionMongoDao {

    private static final String TRANSACTION_ID = "_id";
    private static final String FILE_ID = "fileId";
    private static final String BRAND = "brand";
    private static final String ESTABLISHMENT = "establishment";
    private static final String TRANSACTION_LINE = "transactionLine";
    private static final String VALIDATION_DATE = "validationDate";
    
    private Datastore mDs;

    public NotSyntaxTransactionMongoDao(Datastore datastore) {
        this.mDs = datastore;
    }
    
        public boolean create(NotSyntaxTransaction newTransaction) throws UnreachableHostException {
        try {
            Query<NotSyntaxTransaction> query = mDs.find(NotSyntaxTransaction.class);
            query.field(FILE_ID).equal(newTransaction.getFileId());
            query.field(BRAND).equal(newTransaction.getBrand());
            query.field(ESTABLISHMENT).equal(newTransaction.getEstablishment());
            query.field(TRANSACTION_LINE).equal(newTransaction.getTransactionLine());
            query.field(VALIDATION_DATE).equal(newTransaction.getValidationDate());
            NotSyntaxTransaction transaction = query.get();
            if (transaction != null) {
                throw new PreexistingEntityException(PreexistingEntityException.ERROR_MESSAGE);
            }
            Key<NotSyntaxTransaction> key = mDs.save(newTransaction);
            if (key == null) {
                throw new UnreachableHostException(UnreachableHostException.ERROR_MESSAGE);
            }
            return true;
        } catch (PreexistingEntityException pee) {
            Logger.getLogger(NotSyntaxTransactionMongoDao.class.getName()).log(Level.SEVERE, null, pee);
            return false;
        }
    }
    
    public boolean delete(ObjectId id) throws UnreachableHostException {
        try {
            Query<NotSyntaxTransaction> query = mDs.find(NotSyntaxTransaction.class).field(Mapper.ID_KEY).equal(id);
            NotSyntaxTransaction transaction = query.get();
            if (transaction == null) {
                throw new NonexistentEntityException(NonexistentEntityException.ERROR_MESSAGE);
            }
            WriteResult result = mDs.delete(NotSyntaxTransaction.class, id);
            if (result == null) {
                throw new UnreachableHostException(UnreachableHostException.ERROR_MESSAGE);
            }
            return true;
        } catch (NonexistentEntityException nee) {
            Logger.getLogger(NotSyntaxTransactionMongoDao.class.getName()).log(Level.SEVERE, null, nee);
            return false;
        }
    }
    
    public boolean update(ObjectId id, NotSyntaxTransaction newTransaction) throws UnreachableHostException {
        try {
            Query<NotSyntaxTransaction> query = mDs.createQuery(NotSyntaxTransaction.class).field(Mapper.ID_KEY).equal(id);
            NotSyntaxTransaction transaction = query.get();
            if (transaction == null) {
                throw new NonexistentEntityException(NonexistentEntityException.ERROR_MESSAGE);
            }
            UpdateOperations<NotSyntaxTransaction> update = mDs.createUpdateOperations(NotSyntaxTransaction.class);
            
            update.set(FILE_ID, newTransaction.getFileId());
            update.set(BRAND, newTransaction.getBrand());
            update.set(ESTABLISHMENT, newTransaction.getEstablishment());
            update.set(TRANSACTION_LINE, newTransaction.getTransactionLine());
            update.set(VALIDATION_DATE, newTransaction.getValidationDate());
            
            UpdateResults<NotSyntaxTransaction> result = mDs.update(query, update);
            if (result == null) {
                throw new UnreachableHostException(UnreachableHostException.ERROR_MESSAGE);
            }
            return true;
        } catch (NonexistentEntityException nee) {
            Logger.getLogger(NotSyntaxTransactionMongoDao.class.getName()).log(Level.SEVERE, null, nee);
            return false;
        }
    }
    
    public NotSyntaxTransaction findById(ObjectId id) throws UnreachableHostException {
        return mDs.find(NotSyntaxTransaction.class).field(Mapper.ID_KEY).equal(id).get();
    }
    
    public List<NotSyntaxTransaction> searchInvalidBySynt(Date initDate, Date endDate) throws UnreachableHostException {
        NotSyntaxTransaction transaction = mDs.find(NotSyntaxTransaction.class).get();
        Query<NotSyntaxTransaction> query = mDs.find(NotSyntaxTransaction.class);
        query.filter(VALIDATION_DATE + " >=", initDate);
        query.filter(VALIDATION_DATE + " <=", endDate);
        return query.asList();
    }
}